#!/usr/bin/env python3.10
# -*- encoding: utf-8 -*-
"""
@File    :   user.py
@Time    :   2023/11/15 17:35:48
@Author  :   windstarry 
@Version :   1.0
"""
# here put the import lib
from typing import List
from ninja import ModelSchema, Router, Schema, Field, Query
from django.shortcuts import get_object_or_404
from django.contrib.auth.hashers import make_password
from utils.auth import get_user_info_from_token
from utils.ninja import MyPagination
from system.models import Role, Users
from utils.response import Response
from ninja.pagination import paginate
from utils.crud import retrieve

from system.models import SimpleOperationLog
from utils.enums import OperationMethod, OperationObject


router = Router()


class Filters(Schema):
    id: str = Field(None)
    username: str = Field(None)
    mobile: str = Field(None)


class UserSchemaIn(Schema):
    username: str
    email: str = Field(None)
    mobile: str = Field(None)
    gender: int = Field(1)
    role: List[int] = Field(None)


class CreateUserSchemaIn(UserSchemaIn):
    password: str


class updateUserPasswordIN(Schema):
    id: str = Field(None)
    password: str


class SchemaOut(ModelSchema):
    class Config:
        model = Users
        model_exclude = ["password"]


class Out(Schema):
    msg: str
    code: int
    data: SchemaOut


class UserToRole(Schema):
    user_id: str
    role_id: str


@router.get("/userinfo", response=Out)
def user_info(request):
    user_info = get_user_info_from_token(request)
    return Response(code=200, msg="查询用户详情成功", data=user_info)


@router.get("/user", response=List[SchemaOut])
@paginate(MyPagination)
def user(request, filter: Filters = Query(...)):
    query_set = retrieve(request=request, model=Users, filters=filter)
    return query_set


@router.post("/user", response=SchemaOut)
def create_user(request, data: CreateUserSchemaIn):
    if not isinstance(data, dict):
        data = data.dict()
        # del data["id"]
    data["password"] = make_password(data["password"])
    role_ids = data.pop("role")
    roles = Role.objects.filter(id__in=role_ids)
    query_set = Users(**data)
    query_set.save()
    for role in roles:
        query_set.role.add(str(role.id))
    SimpleOperationLog.add_log(
        request,
        query_set.pk,
        OperationObject.account,
        OperationMethod.create_object,
        f"创建账号(ID={query_set.pk})",
    )
    return query_set


@router.put("/user/{id}", response=SchemaOut)
def update_user(request, id: int, data: UserSchemaIn):
    dict_data = data.dict()
    instance = get_object_or_404(Users, id=id)
    for attr, value in dict_data.items():
        if attr == "role":
            roles = Role.objects.filter(id__in=value)
            instance.role.set(roles)
        else:
            setattr(instance, attr, value)
    instance.save()
    return instance


@router.put("/user/password/{id}", response=SchemaOut, auth=None)
def update_user_password(request, id: int, data: updateUserPasswordIN):
    dict_data = data.dict()
    instance = get_object_or_404(Users, id=id)
    for attr, value in dict_data.items():
        if attr == "password":
            value = make_password(password=value)
            setattr(instance, attr, value)
    instance.save()
    return instance


@router.delete("/user/{id}")
def delete_user(request, id: int):
    instance = get_object_or_404(Users, id=id)
    instance.delete()
    return {"msg": True}


@router.post("/user/role/add", response=SchemaOut)
def user_to_role(request, data: UserToRole):
    user = get_object_or_404(Users, id=data.user_id)
    role = get_object_or_404(Role, id=data.role_id)
    user.role.add(str(role.id))
    user.save()
    return user


@router.post("user/role/del", response=SchemaOut)
def user_del_role(request, data: UserToRole):
    user = get_object_or_404(Users, id=data.user_id)
    role = get_object_or_404(Role, id=data.role_id)
    user.role.remove(role.id)
    return user


@router.post("user/role/upate", response=SchemaOut)
def user_update_role(request, data: UserToRole):
    user = get_object_or_404(Users, id=data.user_id)
    role = get_object_or_404(Role, id=data.role_id)
    user.role.clear()
    user.save()
    return user
